package maquinavirtual;
import java.util.HashMap;
import java.util.Map;

import semantic.CodInstrEnum;

public class MaquinaVirtual {

	public static Object[] pilha = new Object[10000];
	public static int topo = 0;
	public static int ponteiro = 1;
	public static ConjuntoInstrucoes conjInstrucoes = new ConjuntoInstrucoes();
	public static Map<Integer, Object[]> areaInstrucoes = new HashMap<Integer, Object[]>();
	public static Boolean exit = false;

	public void executar() {
		Console console = new Console();
		 Thread inputThread = new Thread(new Runnable() {
		        @Override
		        public void run() {
		        	exit = false;
		    		while (exit != true) {
		    			Object[] instrucao = areaInstrucoes.get(ponteiro);

		    			CodInstrEnum instrEnum = (CodInstrEnum) instrucao[0];

		    			switch (instrEnum) {
		    			case ADD:
		    				conjInstrucoes.ADD();
		    				break;
		    			case ALB:
		    				conjInstrucoes.ALB((int) instrucao[1]);
		    				break;
		    			case ALI:
		    				conjInstrucoes.ALI((int) instrucao[1]);
		    				break;
		    			case ALR:
		    				conjInstrucoes.ALR((int) instrucao[1]);
		    				break;
		    			case ALS:
		    				conjInstrucoes.ALS((int) instrucao[1]);
		    				break;
		    			case BGE:
		    				conjInstrucoes.BGE();
		    				break;
		    			case BGR:
		    				conjInstrucoes.BGR();
		    				break;
		    			case DIF:
		    				conjInstrucoes.DIF();
		    				break;
		    			case DII:
		    				conjInstrucoes.DII();
		    				break;
		    			case DIV:
		    				conjInstrucoes.DIV();
		    				break;
		    			case EQL:
		    				conjInstrucoes.EQL();
		    				break;
		    			case JMF:
		    				conjInstrucoes.JMF((int)instrucao[1]);
		    				break;
		    			case JMP:
		    				conjInstrucoes.JMP((int)instrucao[1]);
		    				break;
		    			case LDB:
		    				conjInstrucoes.LDB(instrucao[1]);
		    				break;
		    			case LDI:
		    				conjInstrucoes.LDI(instrucao[1]);
		    				break;
		    			case LDR:
		    				conjInstrucoes.LDR(instrucao[1]);
		    				break;
		    			case LDS:
		    				conjInstrucoes.LDS(instrucao[1]);
		    				break;
		    			case LDV:
		    				conjInstrucoes.LDV((int) instrucao[1]);
		    				break;
		    			case MOD:
		    				conjInstrucoes.MOD();
		    				break;
		    			case MUL:
		    				conjInstrucoes.MUL();
		    				break;
		    			case NOT:
		    				conjInstrucoes.NOT();
		    				break;
		    			case OR:
		    				conjInstrucoes.OR();
		    				break;
		    			case POW:
		    				conjInstrucoes.POW();
		    				break;
		    			case REA:
		    				conjInstrucoes.REA((int) instrucao[1]);
		    				break;
		    			case SME:
		    				conjInstrucoes.SME();
		    				break;
		    			case SMR:
		    				conjInstrucoes.SMR();
		    				break;
		    			case STC:
		    				conjInstrucoes.STC((int) instrucao[1]);
		    				break;
		    			case STP:
		    				conjInstrucoes.STP();
		    				break;
		    			case STR:
		    				conjInstrucoes.STR((int)instrucao[1]);
		    				break;
		    			case SUB:
		    				conjInstrucoes.SUB();
		    				break;
		    			case WRT:
		    				conjInstrucoes.WRT();
		    				break;
		    			}
		    		}
		        	
		        }
		 });
		 inputThread.start();
	}

	public Map<Integer, Object[]> getAreaInstrucoes() {
		return areaInstrucoes;
	}

	public void setAreaInstrucoes(Map<Integer, Object[]> areaInstrucoes) {
		this.areaInstrucoes = areaInstrucoes;
	}

}
